<script lang="tsx">
import { defineComponent, ref, reactive, computed, watch } from 'vue'
import { ElMessage, ElDialog, ElButton, ElForm, ElFormItem, ElUpload, ElProgress, ElIcon } from 'element-plus'
import { Plus, FileText, CircleX, Video, Loader } from '@vben/icons'
import { useVodPlayer } from '#/hooks/useVodPlayer'
import { obsUpload, obsDelete } from '#/utils/obs'
import { isVideoFile, getVideoDuration, formatDuration } from '#/utils/videoUpload'
import VideoViewer from '#/views/lesson/modules/video-viewer.vue'
import type { ChunkedUploadParams, UploadProgress, DirectUploadParams } from '#/types/vod'
import type { EduRegWorksVO } from '#/api/competition/registration-info'
import { submitWorksApi } from '#/api/competition/registration-info'
import { VbenIcon } from '@vben-core/shadcn-ui';


interface Props {
  visible: boolean
  registrationData?: EduRegWorksVO
}



export default defineComponent({
  name: 'UploadWorksDialog',
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    registrationData: {
      type: Object as () => EduRegWorksVO | undefined,
      default: undefined
    }
  },
  emits: ['update:visible', 'success'],
  setup(props: Props, { emit }: { emit: (event: any, ...args: any[]) => void }) {
    // 表单数据
    const formData = reactive({
      documentFiles: [] as any[],
      videoFiles: [] as any[],
      documentPath: '',
      videoAssetId: ''
    })

    // 表单引用
    const formRef = ref()
    const docUploadRef = ref()
    const videoUploadRef = ref()

    // 弹窗显示控制
    const dialogVisible = computed({
      get: () => props.visible,
      set: (value) => emit('update:visible', value)
    })

    // VOD播放器相关
    const {
      loading: vodLoading,
      error: vodError,
      uploadStatus: vodUploadStatus,
      uploadByChunks,
      uploadDirect,
      reset: resetVod
    } = useVodPlayer()

    // 文档上传状态
    const docUploadProgress = ref(0)
    const isDocUploading = ref(false)
    
    // 视频相关状态
    const videoDuration = ref('')

    // 通用状态
    const error = ref('')
    const isUploading = computed(() => 
      isDocUploading.value || vodUploadStatus.isUploading || vodLoading.value
    )

    // 表单验证规则
    const rules = {
      files: [
        { 
          validator: (_rule: any, _value: any, callback: any) => {
            if (formData.documentFiles.length === 0 && formData.videoFiles.length === 0) {
              callback(new Error('请至少上传一个文件'))
            } else {
              callback()
            }
          }, 
          trigger: 'change' 
        }
      ]
    }

    // 监听弹窗状态
    watch(() => props.visible, (visible) => {
      if (visible) {
        // 弹窗打开时重置表单
        resetForm()
      } else {
        // 弹窗关闭时清理资源
        cleanupResources()
      }
    })

    // 监听VOD错误
    watch(() => vodError.value, (newError) => {
      if (newError) {
        error.value = newError
      }
    })

    // 重置表单
    const resetForm = () => {
      formData.documentFiles = []
      formData.videoFiles = []
      formData.documentPath = ''
      formData.videoAssetId = ''
      docUploadProgress.value = 0
      isDocUploading.value = false
      error.value = ''
      resetVod()
      cleanupVideoResources()
    }

    // 清理视频资源
    const cleanupVideoResources = () => {
      videoDuration.value = ''
    }

    // 清理所有资源
    const cleanupResources = () => {
      cleanupVideoResources()
      resetVod()
    }

    // 文档上传前验证
    const beforeDocUpload = (file: File) => {
      // 检查是否已有文件
      if (formData.documentFiles.length > 0) {
        ElMessage.error('请先删除现有文件')
        return false
      }

      // 验证文件类型
      const allowedTypes = [
        'application/pdf',
        'application/vnd.openxmlformats-officedocument.presentationml.presentation', // pptx
        'application/vnd.ms-powerpoint', // ppt
        'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // docx
        'application/msword', // doc
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // xlsx
        'application/vnd.ms-excel', // xls
      ]
      const allowedExtensions = /\.(pdf|pptx|ppt|docx|doc|xlsx|xls)$/i

      if (!allowedTypes.includes(file.type) && !allowedExtensions.test(file.name)) {
        ElMessage.error('不支持的文件类型，请上传PDF、PPT、DOC、XLS等格式的文件')
        return false
      }

      // 验证文件大小（200MB）
      const maxSize = 200 * 1024 * 1024
      if (file.size > maxSize) {
        ElMessage.error('文档文件大小不能超过200MB')
        return false
      }

      return true
    }

    // 视频上传前验证
    const beforeVideoUpload = async (file: File) => {
      // 检查是否已有文件
      if (formData.videoFiles.length > 0) {
        ElMessage.error('请先删除现有文件')
        return false
      }

      // 验证文件类型
      if (!isVideoFile(file)) {
        ElMessage.error('请选择视频文件')
        return false
      }

      // 验证文件大小（2.5GB）
      const maxSize = 2.5 * 1024 * 1024 * 1024
      if (file.size > maxSize) {
        ElMessage.error('视频文件大小不能超过2.5GB')
        return false
      }

      // 获取视频时长
      try {
        const duration = await getVideoDuration(file)
        videoDuration.value = formatDuration(duration)
      } catch (error) {
        console.warn('无法获取视频时长:', error)
      }

      return true
    }

    // 处理文档上传
    const handleDocUpload = async (options: any) => {
      const { file } = options
      isDocUploading.value = true
      docUploadProgress.value = 0

      try {
        const fileName = `works/doc_${Date.now()}_${file.name}`
        
        await new Promise<void>((resolve, reject) => {
          obsUpload({
            Key: fileName,
            SourceFile: file,
            ContentType: file.type
          }, (err: any, _result: any, uploadedKey: string) => {
            if (err) {
              reject(err)
              return
            }
            
            // 清除表单验证
            if (formRef.value?.clearValidate) {
              formRef.value.clearValidate('files')
            }
            
            formData.documentPath = uploadedKey
            docUploadProgress.value = 100
            resolve()
          })
        })
        
        ElMessage.success('文档上传成功')
      } catch (err) {
        console.error('文档上传失败:', err)
        // 移除文件
        formData.documentFiles = []
      } finally {
        isDocUploading.value = false
      }
    }

    // 处理视频上传
    const handleVideoUpload = async (options: any) => {
      const { file } = options

      try {
        // 根据文件大小选择上传方式
        let assetId: string
        
        if (file.size <= 20 * 1024 * 1024) {
          // 小于20MB使用直接上传
          const directParams: DirectUploadParams = {
            file,
            title: `视频_${Date.now()}`,
            description: '作品介绍视频',
            autoPublish: true
          }
          const result = await uploadDirect(directParams)
          assetId = result.assetId
        } else {
          // 大于20MB使用分段上传
          const chunkedParams: ChunkedUploadParams = {
            file,
            title: `视频_${Date.now()}`,
            description: '作品介绍视频',
            autoPublish: true,
            chunkSize: 10 * 1024 * 1024,
            onProgress: (progress: UploadProgress) => {
              console.log('VOD上传进度:', progress)
            }
          }
          assetId = await uploadByChunks(chunkedParams)
        }

        // 清除表单验证
        if (formRef.value?.clearValidate) {
          formRef.value.clearValidate('files')
        }

        formData.videoAssetId = assetId
        ElMessage.success('视频上传成功')
      } catch (err) {
        console.error('视频上传失败:', err)
        // 移除文件
        formData.videoFiles = []
        cleanupVideoResources()
      }
    }

    // 移除文档文件
    const removeDocFile = (_file: any) => {
      if (formData.documentPath) {
        obsDelete({
          Key: formData.documentPath
        }, (err: any) => {
          if (err) {
            ElMessage.error('删除文件失败')
            return
          }
          formData.documentPath = ''
          ElMessage.success('文件删除成功')
        })
      }
      formData.documentFiles = []
    }

    // 移除视频文件
    const removeVideoFile = (_file: any) => {
      formData.videoFiles = []
      formData.videoAssetId = ''
      cleanupVideoResources()
    }

    // 选择文档文件
    const selectDocFile = () => {
      if (formData.documentFiles.length > 0) {
        ElMessage.error('请先删除现有文件')
        return
      }
      const inputElement = docUploadRef.value?.$el?.querySelector('input[type="file"]')
      if (inputElement) {
        inputElement.click()
      }
    }

    // 选择视频文件
    const selectVideoFile = () => {
      if (formData.videoFiles.length > 0) {
        ElMessage.error('请先删除现有文件')
        return
      }
      const inputElement = videoUploadRef.value?.$el?.querySelector('input[type="file"]')
      if (inputElement) {
        inputElement.click()
      }
    }

    // 提交表单
    const handleSubmit = async () => {
      try {
        await formRef.value?.validate()
        
        if (!props.registrationData?.id) {
          ElMessage.error('缺少报名信息ID')
          return
        }

        // 构建更新数据
        const updateData: EduRegWorksVO = {
          id: props.registrationData.id
        }

        // 添加文档信息到worksIntroduceFile字段
        if (formData.documentFiles.length > 0 && formData.documentPath) {
          updateData.worksIntroduceFile = formData.documentPath
        }

        // 添加视频信息到videoAssetId字段
        if (formData.videoFiles.length > 0 && formData.videoAssetId) {
          updateData.videoAssetId = formData.videoAssetId
        }

        // 调用提交作品API
        await submitWorksApi(updateData)

        const result = {
          worksIntroduceFile: updateData.worksIntroduceFile,
          videoAssetId: updateData.videoAssetId,
          registrationId: props.registrationData.id
        }

        emit('success', result)
        ElMessage.success('作品上传成功！')
        handleClose()
      } catch (err) {
        console.error('提交失败:', err)
      }
    }

    // 关闭弹窗
    const handleClose = () => {
      if (isUploading.value) {
        ElMessage.warning('上传中，请稍后...')
        return
      }
      emit('update:visible', false)
    }

    // 渲染文档上传区域
    const renderDocumentUpload = () => (
      <ElFormItem label="作品讲解课件">
        <div class="flex items-center mb-4">
          <ElUpload
            ref={docUploadRef}
            class="hidden"
            accept=".pdf,.pptx,.ppt,.docx,.doc,.xlsx,.xls"
            v-model:file-list={formData.documentFiles}
            action="#"
            http-request={handleDocUpload}
            on-remove={removeDocFile}
            before-upload={beforeDocUpload}
            auto-upload={true}
            limit={1}
            show-file-list={false}
            style="display: none;"
          />
          <ElButton icon={Plus} onClick={selectDocFile}>上传课件</ElButton>
          <div class="text-xs text-gray-500 ml-2">
            支持格式：PDF、PPT、DOC、XLS等，大小不超过200MB
          </div>
        </div>

        {/* 文档文件列表 */}
        {formData.documentFiles.length > 0 && (
          <div class="mt-[8px] w-full">
            {formData.documentFiles.map((file, index) => (
              <div key={index} class="w-full px-[5px] bg-blue-50 rounded-md border border-blue-200">
                <div class="flex items-center justify-between">
                  <div class="flex items-center">
                    <ElIcon class="text-blue-500 mr-2">
                      <FileText />
                    </ElIcon>
                    <div class="flex flex-col">
                      <span class="text-sm text-gray-700">{file.name}</span>
                    </div>
                  </div>
                  <ElButton size="small" icon={CircleX} link onClick={() => removeDocFile(file)} />
                </div>
              </div>
            ))}
          </div>
        )}
      </ElFormItem>
    )

    // 渲染视频上传区域
    const renderVideoUpload = () => (
      <ElFormItem label="作品介绍视频">
        <div class="flex items-center mb-4">
          <ElUpload
            ref={videoUploadRef}
            class="hidden"
            accept="video/*"
            v-model:file-list={formData.videoFiles}
            action="#"
            http-request={handleVideoUpload}
            on-remove={removeVideoFile}
            before-upload={beforeVideoUpload}
            auto-upload={true}
            limit={1}
            show-file-list={false}
            style="display: none;"
          />
          <ElButton icon={Plus} onClick={selectVideoFile}>上传视频</ElButton>
          <div class="text-xs text-gray-500 ml-2">
            支持格式：MP4、AVI、MOV等，大小不超过2.5GB
          </div>
        </div>

        {/* 视频上传进度 */}
        {vodUploadStatus.isUploading && (
          <div class="mt-4 p-4 bg-white border rounded-md">
            <div class="flex items-center justify-between mb-2">
              <span class="text-sm text-gray-600">{vodUploadStatus.message}</span>
              <span class="text-sm text-blue-600">{vodUploadStatus.progress}%</span>
            </div>
            <ElProgress 
              percentage={vodUploadStatus.progress} 
              status={vodUploadStatus.progress === 100 ? 'success' : undefined}
              show-text={false} 
            />
            {vodUploadStatus.totalChunks > 1 && (
              <div class="mt-2 text-xs text-gray-500 text-center">
                分段进度: {vodUploadStatus.currentChunk}/{vodUploadStatus.totalChunks}
              </div>
            )}
          </div>
        )}

        {/* 视频预览区域 */}
        <div class="w-[75%]">
          {formData.videoFiles.length > 0 ? (
            /* 有视频文件时显示文件信息和预览 */
            <div class="px-3 py-2 bg-blue-50 rounded-md border border-blue-200">
              <div class="flex items-center justify-between mb-3">
                <div class="flex items-center">
                  <span class="text-sm text-gray-700">{formData.videoFiles[0].name}</span>
                </div>
                <ElButton size="small" icon={CircleX} link onClick={() => removeVideoFile(formData.videoFiles[0])} />
              </div>
              
              {/* 视频预览 */}
              {formData.videoAssetId ? (
                /* 上传完成后使用VideoViewer预览VOD资源 */
                <VideoViewer
                  path={`vod://${formData.videoAssetId}`}
                  vodAssetId={formData.videoAssetId}
                />
              ) : (
                /* 上传中显示loading状态 */
                <div class="w-full h-[150px] border border-gray-300 rounded-md flex flex-col items-center justify-center">
                  <VbenIcon icon={Loader} />
                  <div class="text-sm text-gray-500">视频上传中，请稍候...</div>
                </div>
              )}
            </div>
          ) : (
            /* 没有视频时显示缺省框 */
            <div class="w-full h-48 border border-gray-300 rounded-lg flex flex-col items-center justify-center">
              <VbenIcon icon={Video} />
              <div class="">上传视频</div>
            </div>
          )}
        </div>
      </ElFormItem>
    )

    return () => (
      <ElDialog
        v-model={dialogVisible.value}
        title="上传作品"
        width="650px"
        close-on-click-modal={false}
        close-on-press-escape={false}
        onClose={handleClose}
        v-slots={{
          footer: () => (
              <div class="flex justify-end space-x-3">
                <ElButton onClick={handleClose} disabled={isUploading.value}>
                  取消
                </ElButton>
                <ElButton 
                  type="primary" 
                  onClick={handleSubmit}
                  loading={isUploading.value}
                >
                  {isUploading.value ? '上传中...' : '确定'}
                </ElButton>
              </div>
            )
        }}
      >
        <ElForm
          ref={formRef}
          model={formData}
          rules={rules}
          class="min-h-[300px]"
        >
            {/* 文档上传区域 */}
            {renderDocumentUpload()}
            {/* 视频上传区域 */}
            {renderVideoUpload()}
        </ElForm>
      </ElDialog>
    )
  }
})
</script>

<style scoped>
.hidden {
  display: none !important;
  visibility: hidden !important;
  pointer-events: none !important;
  position: absolute !important;
  left: -9999px !important;
}
</style>
